package com.hymane.expandtextview;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.Text;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Component;
import ohos.agp.components.Image;
import ohos.agp.components.AttrSet;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.LayoutScatter;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.data.DatabaseHelper;
import ohos.data.preferences.Preferences;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;

/**
 * Author   :hymanme
 * Email    :hymanme@163.com
 * Create at 2016/8/12
 * Description: 可折叠的textview控件，点击下拉按钮可展开textview全部内容，再次点击收回。
 */
public class ExpandTextView extends DirectionalLayout implements Component.ClickedListener {
    public static final int DEFAULT_LINT_HEIGHT = 61;
    public static final int DEFAULT_TITLE_TEXT_COLOR = 0X8A000000;
    public static final int DEFAULT_CONTENT_TEXT_COLOR = 0XDE000000;
    public static final int DEFAULT_HINT_TEXT_COLOR = 0XDE000000;
    public static final int DEFAULT_MIN_LINES = 4;
    public static final int DEFAULT_TITLE_TEXT_SIZE = 16;
    public static final int DEFAULT_CONTENT_TEXT_SIZE = 13;
    public static final int DEFAULT_HINT_TEXT_SIZE = 12;
    public static final int DEFAULT_ANIMATION_DURATION = 600;
    private Context mContext;
    //标题
    private String title;
    //内容文字
    private String content;
    //展开后显示的文字
    private String foldHint;
    //折叠起来后显示的文字
    private String expandHint;
    //标题文字颜色
    private int titleTextColor;
    //内容文字颜色
    private int contentTextColor;
    //查看更多文字颜色
    private int hintTextColor;
    //查看更多前面显示的小图标
    private int indicateImage;
    //内容区域最少显示几行文字
    private int minVisibleLines = DEFAULT_MIN_LINES;
    //标题字体大小
    private int titleTextSize;
    //内容字体大小
    private int contentTextSize;
    //提示字体大小
    private int hintTextSize;
    //展开和折叠动画持续时间
    private int animationDuration;

    private Text mTitleView;
    private Text mContentView;
    private Text mHintView;
    private Image mIndicateImage;
    private DependentLayout mShowMore;
    private OnReadMoreClickListener mListener;
    private boolean flag;
    private ComponentContainer.LayoutConfig layoutParams;
    private AnimatorProperty mAnimator;
    private AnimatorValue animator1;
    private int maxHeight = -1;
    private EventHandler handler;
    private Preferences preferences;
    public int getMaxHeight() {
        return maxHeight;
    }

    public void setMaxHeight(int maxHeight) {
        this.maxHeight = maxHeight;
    }

    public ExpandTextView(Context context) {
        this(context, null);
    }

    public ExpandTextView(Context context, AttrSet attrs) {
        this(context, attrs, "");
    }

    public ExpandTextView(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        init();
        setOrientation(VERTICAL);
        if (attrs != null) {
            title = attrs.getAttr("title").isPresent() ?
                    attrs.getAttr("title").get().getStringValue() : "";
            content = attrs.getAttr("contentText").isPresent() ?
                    attrs.getAttr("contentText").get().getStringValue() : "";
            foldHint = attrs.getAttr("foldHint").isPresent() ?
                    attrs.getAttr("foldHint").get().getStringValue() : "";
            expandHint = attrs.getAttr("expandHint").isPresent() ?
                    attrs.getAttr("expandHint").get().getStringValue() : "";
            titleTextColor = attrs.getAttr("titleTextColor").isPresent() ?
                    attrs.getAttr("titleTextColor").get().getColorValue().getValue() : DEFAULT_TITLE_TEXT_COLOR;
            contentTextColor = attrs.getAttr("contentTextColor").isPresent() ?
                    attrs.getAttr("contentTextColor").get().getColorValue().getValue() : DEFAULT_CONTENT_TEXT_COLOR;
            hintTextColor = attrs.getAttr("hintTextColor").isPresent() ?
                    attrs.getAttr("hintTextColor").get().getColorValue().getValue() : DEFAULT_HINT_TEXT_COLOR;

            indicateImage = attrs.getAttr("indicateImage").isPresent() ?
                    attrs.getAttr("indicateImage").get().getIntegerValue() : ResourceTable.Media_ic_arrow_down_light_round;
            minVisibleLines = attrs.getAttr("minVisibleLines").isPresent() ?
                    attrs.getAttr("minVisibleLines").get().getIntegerValue() : DEFAULT_MIN_LINES;
            titleTextSize = attrs.getAttr("titleTextSize").isPresent() ?
                    attrs.getAttr("titleTextSize").get().getIntegerValue() : DEFAULT_TITLE_TEXT_SIZE;
            contentTextSize = attrs.getAttr("contentTextSize").isPresent() ?
                    attrs.getAttr("contentTextSize").get().getIntegerValue() : DEFAULT_CONTENT_TEXT_SIZE;
            animationDuration = attrs.getAttr("animationDuration").isPresent() ?
                    attrs.getAttr("animationDuration").get().getIntegerValue() : DEFAULT_ANIMATION_DURATION;

        }
        mTitleView.setText(title);
        mTitleView.setTextSize(titleTextSize, Text.TextSizeType.FP);
        mTitleView.setTextColor(new Color(titleTextColor));

        mContentView.setText(content);
        mContentView.setTextSize(contentTextSize, Text.TextSizeType.FP);
        mContentView.setTextColor(new Color(contentTextColor));

        mHintView.setText(expandHint);
        mHintView.setTextSize(DEFAULT_HINT_TEXT_SIZE, Text.TextSizeType.FP);
        mHintView.setTextColor(new Color(contentTextColor));

        if (indicateImage == 0) {
            indicateImage = ResourceTable.Media_ic_arrow_down_light_round;
        }
        mIndicateImage.setImageAndDecodeBounds(indicateImage);
        mShowMore.setClickedListener(this::onClick);
    }

    private void init() {
        handler = new EventHandler(EventRunner.getMainEventRunner());
        LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_expand_text_view, this, true);
        mTitleView = (Text) findComponentById(ResourceTable.Id_tv_title);
        mContentView = (Text) findComponentById(ResourceTable.Id_tv_content);
        mHintView = (Text) findComponentById(ResourceTable.Id_tv_more_hint);
        mIndicateImage = (Image) findComponentById(ResourceTable.Id_iv_arrow_more);
        mShowMore = (DependentLayout) findComponentById(ResourceTable.Id_rl_show_more);
        layoutParams = mContentView.getLayoutConfig();
        layoutParams.height = getMinMeasureHeight();
        mContentView.setLayoutConfig(layoutParams);
        mAnimator = mIndicateImage.createAnimatorProperty();

    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
        mTitleView.setText(title);
    }

    public String getContent() {
        return content;
    }


    public void setContent(String content) {
        this.content = content;
        mContentView.setText(content);

    }

    public String getFoldHint() {
        return foldHint;
    }

    public void setFoldHint(String foldHint) {
        this.foldHint = foldHint;
    }

    public String getExpandHint() {
        return expandHint;
    }

    public void setExpandHint(String expandHint) {
        this.expandHint = expandHint;
    }

    public int getTitleTextColor() {
        return titleTextColor;
    }

    public void setTitleTextColor(int titleTextColor) {
        this.titleTextColor = titleTextColor;
        mTitleView.setTextColor(new Color(titleTextColor));
    }

    public int getContentTextColor() {
        return contentTextColor;
    }

    public void setContentTextColor(int contentTextColor) {
        this.contentTextColor = contentTextColor;
        mContentView.setTextColor(new Color(contentTextColor));
    }

    public int getHintTextColor() {
        return hintTextColor;
    }

    public void setHintTextColor(int hintTextColor) {
        this.hintTextColor = hintTextColor;
        mHintView.setTextColor(new Color(hintTextColor));
    }

    public int getIndicateImage() {
        return indicateImage;
    }

    public void setIndicateImage(int indicateImage) {
        this.indicateImage = indicateImage;
        mIndicateImage.setImageAndDecodeBounds(indicateImage);
    }


    public int getMinVisibleLines() {
        return minVisibleLines;
    }

    public void setMinVisibleLines(int minVisibleLines) {
        this.minVisibleLines = minVisibleLines;
        ComponentContainer.LayoutConfig layoutParams = mContentView.getLayoutConfig();
        layoutParams.height = getMinMeasureHeight();
        mContentView.setLayoutConfig(layoutParams);
    }

    public float getTitleTextSize() {
        return titleTextSize;
    }

    /**
     * 设置字体大小
     *
     * @param titleTextSize sp为单位
     */
    public void setTitleTextSize(int titleTextSize) {
        this.titleTextSize = titleTextSize;
        mTitleView.setTextSize(titleTextSize);
    }

    public float getContentTextSize() {
        return contentTextSize;
    }

    /**
     * 设置字体大小
     *
     * @param contentTextSize sp为单位
     */
    public void setContentTextSize(int contentTextSize) {
        this.contentTextSize = contentTextSize;
        ComponentContainer.LayoutConfig layoutParams = mContentView.getLayoutConfig();
        layoutParams.height = getMinMeasureHeight();
        mContentView.setLayoutConfig(layoutParams);
    }

    public float getHintTextSize() {
        return hintTextSize;
    }

    /**
     * 设置字体大小
     *
     * @param hintTextSize sp为单位
     */
    public void setHintTextSize(int hintTextSize) {
        this.hintTextSize = hintTextSize;
        mHintView.setTextSize(hintTextSize);
    }

    public Component getTitleView() {
        return mTitleView;
    }

    public int getAnimationDuration() {
        return animationDuration;
    }

    public void setAnimationDuration(int animationDuration) {
        this.animationDuration = animationDuration;
    }

    public OnReadMoreClickListener getReadMoreListener() {
        return mListener;
    }

    public void setOnReadMoreListener(OnReadMoreClickListener mListener) {
        this.mListener = mListener;
    }

    @Override
    public void onClick(Component component) {
        if (component.getId() == ResourceTable.Id_rl_show_more) {
            expand();
        }
    }

    /**
     * 获取TextView最大高度
     *
     * @return int 最大测量高度
     */
    public int getMaxMeasureHeight() {
        int str = mContentView.getText().length();
        int lineNmu = str / 22 + 1;
        int height = lineNmu * DEFAULT_LINT_HEIGHT;
        if (maxHeight != -1) {
            height = getSaveHeight();
            System.out.println("--------------"+height);
        }
        if (maxHeight > 3000) {
            maxHeight = 3000;
        }
        return height;
    }

    public int getMinMeasureHeight() {
        return DEFAULT_LINT_HEIGHT * minVisibleLines;
    }

    /**
     * 折叠和展开
     */
    private void expand() {

        int startHeight;
        int targetHeight;
        if (!flag) {
            if (mAnimator.isRunning()) {
                return;
            }
            mAnimator.reset();
            mAnimator.setDuration(1000).rotate(0).rotate(360).start();
            handler.postTask(() -> mAnimator.pause(), 500);
            flag = true;
            startHeight = getMinMeasureHeight();
            targetHeight = getMaxMeasureHeight();
            if (targetHeight < startHeight) {
                targetHeight = startHeight;
            }
            mHintView.setText(foldHint);

            if (mListener != null) {
                mListener.onExpand();
            }
        } else {
            if (mAnimator.isPaused()) {
                mAnimator.resume();
            }else  {
                return;
            }


            flag = false;
            startHeight = getMaxMeasureHeight();
            targetHeight = getMinMeasureHeight();

            if (startHeight < targetHeight) {
                startHeight = targetHeight;
            }
            mHintView.setText(expandHint);
            if (mListener != null) {
                mListener.onFold();
            }
        }
        if (animationDuration < 0) {
            animationDuration = DEFAULT_ANIMATION_DURATION;
        }
        layoutParams = mContentView.getLayoutConfig();

        if (animator1 == null) {
            animator1 = new AnimatorValue();
        }
        animator1.setDuration(animationDuration);
        int finalStartHeight = startHeight;
        int finalTargetHeight = targetHeight;
        animator1.setValueUpdateListener((animatorValue, v) -> {
            layoutParams.height = finalStartHeight + (int) ((finalTargetHeight - finalStartHeight) * v);
            mContentView.setLayoutConfig(layoutParams);
        });
        animator1.start();

    }
    private Preferences getPreferences() {
        if (preferences == null) {
            DatabaseHelper databaseHelper = new DatabaseHelper(mContext);
            preferences = databaseHelper.getPreferences("app_preference.xml");
        }
        return preferences;
    }
    public void saveHeight(int height) {
        getPreferences().putInt("height", height);
        getPreferences().flush();
    }
    public int  getSaveHeight() {

      return   getPreferences().getInt("height",DEFAULT_LINT_HEIGHT);

    }
}
